util: New gstrsub version after some valgrind errors.
authoroliskoli <oliskoli>
Tue, 1 Apr 2008 18:03:18 +0000 (18:03 +0000)
committeroliskoli <oliskoli>
Tue, 1 Apr 2008 18:03:18 +0000 (18:03 +0000)
util.c

diff --git a/util.c b/util.c
index 17807097f0093a0e9a0cdc26e81a0c7db6d8ab90..8ded3ea2a3df63a75ffdb185a6e5da93792166b7 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1103,18 +1103,30 @@ strsub(const char *s, const char *search, const char *replace)
 char *
 gstrsub(const char *s, const char *search, const char *replace)
 {
-       char *o = xstrdup(s);
-       char *tsearch = o;
-       // The tsearch silliness here is in case we decide to replace a string
-       // with a string that's a superset of that string.  Replacing ";" 
-       // with "\\;" in the vcf writer is our problem child.
-       while ((tsearch = strstr(tsearch, search))) {
-               char *oo = o;
-               o = strsub(o, search, replace);
-               tsearch = tsearch + strlen(replace);
-               xfree(oo);
+       int ooffs = 0;
+       char *o, *c;
+       char *src = (char *)s;
+       int olen = strlen(src);
+       int slen = strlen(search);
+       int rlen = strlen(replace);
+
+       o = xmalloc(olen + 1);
+       
+       while ((c = strstr(src, search))) {
+               olen += (rlen - slen);
+               o = xrealloc(o, olen + 1);
+               memcpy(o + ooffs, src, c - src);
+               ooffs += (c - src);
+               src = c + slen;
+               if (rlen) {
+                       memcpy(o + ooffs, replace, rlen);
+                       ooffs += rlen;
+               }
        }
 
+       if (ooffs < olen)
+               memcpy(o + ooffs, src, olen - ooffs);
+       o[olen] = '\0';
        return o;
 }